<!-- 字段库 -->
<template>
  <div class="tree-warp">
    <!-- <div class="title">字段库</div> -->
    <a-input-search v-model="searchValue" style="margin-bottom: 20px;" placeholder="输入字段名称搜索" />
    <template v-for="item in treeData">
      <div class="group" :key="item.id">
        <div class="group-header">{{ item.name }}</div>
        <div class="group-item__title" v-for="cItem in item.children" :key="cItem.id">
          <a-checkbox
            :checked="cItem.checkedAll"
            :indeterminate="cItem.indeterminate"
            :disabled="cItem.disabled"
            style="color: #86909C"
            @change="onCheckAllChange($event, cItem)"
          >
            {{ cItem.name }}
          </a-checkbox>
          <div class="group-item__list">
            <template v-if="cItem.children && cItem.children.length">
              <template v-for="v in cItem.children">
                <template v-if="searchValue">
                  <div
                    v-if="v.name && v.name.indexOf(searchValue) > -1"
                    style="margin-bottom: 16px; width: 200px;display: flex;align-items: center;"
                    :key="v.id"
                  >
                    <a-checkbox
                      :value="v.id"
                      :disabled="v.disabled"
                      :checked="v.disabled ? true : cItem.checkedIds.includes(v.id)"
                      @change="onCheckChange($event, v)"
                    >
                      <span>{{ v.name.substr(0, v.name.indexOf(searchValue)) }}</span>
                      <span style="color: #f50">{{ searchValue }}</span>
                      <span>{{ v.name.substr(v.name.indexOf(searchValue) + searchValue.length) }}</span>
                    </a-checkbox>
                    <img :src="v.icon" style="width: 40px;" />
                  </div>
                </template>
                <div v-else style="margin-bottom: 16px; width: 200px;display: flex;align-items: center;" :key="v.id">
                  <a-checkbox
                    :value="v.id"
                    :disabled="v.disabled"
                    :checked="v.disabled ? true : cItem.checkedIds.includes(v.id)"
                    @change="onCheckChange($event, v)"
                  >
                    <span >{{ v.name }}</span>
                  </a-checkbox>
                  <img :src="v.icon" style="width: 40px;" />
                </div>
              </template>
            </template>
          </div>
        </div>
      </div>
    </template>
  </div>
</template>

<script>
import { uniq } from 'lodash-es'

export default {
  props: {
    // 字段库列表
    fieldLibraryList: {
      type: Array,
      required: true,
      default: () => []
    },
    //已选中集合
    checkedKeys: {
      type: Array,
      required: true,
      default: () => []
    },
    //禁用集合
    disabledKeys: {
      type: Array,
      required: true,
      default: () => []
    },
    stageIndex: {
      type: Number,
      required: true
    }
  },
  components: {},
  data() {
    return {
      treeData: [],
      requestData: [],
      searchValue: '',
      searchKeys: []
    }
  },
  computed: {},
  watch: {
    checkedKeys(val) {
      this.treeData = this.getTreeData(this.requestData)
    },
    stageIndex(val) {}
  },
  methods: {
    getTreeData(data) {
      return data.map(item => {
        const children = item.children || []
        const childrenTreeData = this.getTreeData(children)
        const cIds = children.map(v => v.id)
        const disabledIds = childrenTreeData.reduce((prev, item) => {
          if (item.disabled) {
            prev.push(item.id)
          }
          return prev
        }, [])

        const intersect = this.checkedKeys.filter(function(v) {
          return cIds.indexOf(v) > -1
        })

        const checkedAll =
          intersect.length === cIds.length ||
          disabledIds.length === cIds.length ||
          [...disabledIds, ...intersect].length === cIds.length

        let indeterminate = false
        const ids = [...disabledIds, ...intersect]
        if (ids.length && ids.length < cIds.length) {
          indeterminate = true
        }
        return {
          ...item,
          label: item.name,
          disabled:
            children && children.length
              ? this.isInclude(this.disabledKeys, children)
              : this.disabledKeys.includes(item.id) || (item.itemType === 'ApplyTable' && this.stageIndex === 0),
          checkedAll: checkedAll,
          indeterminate: indeterminate,
          checkedIds: intersect,
          disabledIds,
          children: childrenTreeData
        }
      })
    },

    onCheckAllChange(e, cItem) {
      const { checked } = e.target
      const cIds = cItem.children.map(v => v.id)
      const checkIds = cIds.filter(v => !cItem.disabledIds.includes(v))
      if (checked) {
        this.$emit('setCheckedKeys', uniq([...this.checkedKeys, ...checkIds]))
      } else {
        this.$emit(
          'setCheckedKeys',
          this.checkedKeys.filter(v => !checkIds.includes(v))
        )
      }
      this.checkField(cItem, checked)
    },

    onCheckChange(e, item) {
      const { checked } = e.target
      if (checked) {
        this.$emit('setCheckedKeys', uniq([...this.checkedKeys, item.id]))
      } else {
        this.$emit(
          'setCheckedKeys',
          this.checkedKeys.filter(v => v !== item.id)
        )
      }

      this.checkField(item, checked)
    },

    isInclude(arr1, arr2) {
      if (!arr2.length) return false
      return arr2.every(val => arr1.includes(val.id))
    },

    checkField(data, checked) {
      let module = this.treeData.find(f => f.moduleType === data.moduleType)

      if (data.moduleType === 3) {
        if (data.parentId === 0) {
          data.children.forEach(item => {
            this.$emit('checkField', item, checked, item)
          })
        } else {
          this.$emit('checkField', data, checked, module)
        }
      } else {
        this.$emit('checkField', data, checked, module)
      }
    }
  },
  created() {
    const data = this.fieldLibraryList || []
    this.requestData = data
    this.treeData = this.getTreeData(data)
  },
  mounted() {}
}
</script>
<style lang="less" scoped>
.tree-warp {
  .title {
    font-size: 16px;
    color: #333;
    font-weight: bold;
    padding: 20px 0;
    text-align: center;
  }

  .group {
    padding: 16px;
    margin-bottom: 20px;
    &-header {
      font-size: 20px;
      color: #1d2129;
      margin-bottom: 16px;
      border-bottom: 1px solid #e5e6eb;
    }
    &-item__list {
      margin-left: 20px;
      display: flex;
      flex-wrap: wrap;
      margin-top: 12px;
      // margin-bottom: 20px;
    }
  }
}
</style>
